/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 combat_object_base.h

	$Header: /heroes4/combat_object_base.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( COMBAT_OBJECT_BASE_H_INCLUDED )
#define COMBAT_OBJECT_BASE_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "battlefield_metrics.h"
#include "map_point.h"
#include "map_rect.h"
#include "screen_point.h"

class t_battlefield;
class t_combat_footprint;
enum  t_direction;

// -----------------------------------------------------------------------
// t_abstract_combat_object class
// -----------------------------------------------------------------------

class t_combat_object_base 
{
public:
	virtual ~t_combat_object_base();

	// Types
	// Member functions
	virtual bool				can_be_attacked() const;
	t_map_point_2d				get_cell_position() const;
	t_map_rect_2d				get_cell_rect() const;
	t_combat_footprint const&	get_footprint() const;
	t_map_point_3d              get_footprint_center() const;
	t_map_point_2d				get_footprint_center( t_map_point_2d const& cell_point ) const;
	virtual int					get_footprint_size() const = 0;
	int							get_half_footprint_size() const;
	t_map_point_3d const &		get_position() const;
	bool						in_footprint( t_map_point_2d const& point ) const;
	virtual bool				is_creature() const;
	virtual bool				is_permanent() const;
protected:
	t_map_point_3d	m_position;
};

inline t_map_point_2d t_combat_object_base::get_cell_position() const
{
	return m_position >> k_battlefield_subcell_shift;
}

inline t_map_point_3d t_combat_object_base::get_footprint_center() const
{
	int offset = get_footprint_size() << (k_battlefield_subcell_shift - 1);
	return m_position + t_map_point_2d( offset, offset );
}

inline int t_combat_object_base::get_half_footprint_size() const
{
	return get_footprint_size() << (k_battlefield_subcell_shift - 1);
}

inline t_map_point_3d const & t_combat_object_base::get_position() const
{
	return m_position;
}

// -----------------------------------------------------------------------
// determine direction from one actor to another
// -----------------------------------------------------------------------
t_direction get_direction( t_map_point_2d const& left_position,
						   t_map_point_2d const& right_position );
// ---------------------------------------------------------
// helper functions
// ---------------------------------------------------------
t_direction get_direction( t_combat_object_base const& left, 
						   t_map_point_2d              left_position,
						   t_combat_object_base const& right,
						   t_map_point_2d              right_position );

// -----------------------------------------------------------------------
// determine direction from one actor to another
// -----------------------------------------------------------------------
inline t_direction get_direction( t_combat_object_base const& left, 
								  t_combat_object_base const& right,
								  t_map_point_2d       const& right_position )
{
	return get_direction( left, left.get_cell_position(), right, right_position );
}


// -----------------------------------------------------------------------
// determine direction from one actor to another
// -----------------------------------------------------------------------
inline t_direction get_direction( t_combat_object_base const& left, 
								  t_map_point_2d       const& left_position,
								  t_combat_object_base const& right )
{
	return get_direction( left, left_position, right, right.get_cell_position() );
}

// -----------------------------------------------------------------------
// determine direction from one actor to another
// -----------------------------------------------------------------------
inline t_direction get_direction( t_combat_object_base const& left, 
								  t_combat_object_base const& right )
{
	return get_direction( left, left.get_cell_position(), right, right.get_cell_position() );
}


#endif // COMBAT_OBJECT_BASE_H_INCLUDED